﻿using System;
using System.Collections.Generic;
using SdmxMl.Common;
using SdmxMl.Manager;
using SdmxMl.Structure;
using SdmxMl.GenericMetadata;
using System.Text;
using Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Configuration;

namespace Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Meta
{
    public class BookSaver
    {
        #region Activity

        public List<string> GetActivityList(string lg)
        {
            List<string> Activities = new List<string>();
            SmManager sm = new SmManager();
            ArtefactRefTyped art = new ArtefactRefTyped(SdmxArtefactType.CategorySchemes, "CH1_SMS+CAT_ACTIVITIES+1.0");
            sm.GetArtefact(art.Type, art, true);
            CategorySchemeType catScheme = sm.GetArtefact(art) as CategorySchemeType;

            // all at 1st level
            foreach (Category cat in catScheme.CategoryList)
            {
                Activities.Add (cat.Id + " - " + cat.Name.GetForLanguage(lg));
            }

            return Activities;
        }

        #endregion

        #region Book persistance

        public void SaveBook(BookHierarchy book, BookConfiguration cfg, string activityCode, string metaFullId)
        {
            ArtefactRefTyped art = new ArtefactRefTyped(SdmxArtefactType.MetadataSet, metaFullId);
            SmManager sm = new SmManager();

            // Fetch MSD and report for Book  content
            MetadataSetType metadataSet = CreateMetaset(art);
            MetadataStructureDefinitionType msd = sm.GetArtefact(SdmxArtefactType.MetadataStructureDefinitions,
               metadataSet.MetadataStructureRef, true) as MetadataStructureDefinitionType;
            ReportStructureType report = msd.ReportStructureList[0];


            AttributeValueSetType atv = new AttributeValueSetType(msd, report, metadataSet);
            // The target values
            atv.TargetValuesTypeList.SetComponentValue("ACTIVITY", activityCode);
            atv.ReportedAttributeList.Clear();
 
            // The reported modules
            foreach (HierarchyNode moduleTypeNode in book.Nodes)
            {
                foreach (HierarchyNode moduleNode in moduleTypeNode.Nodes)
                {
                    // Create a module Report with children as type and identity
                    ReportedAttributeType raModule = new ReportedAttributeType();
                    raModule.ConceptID = BookProvider.MSD_BOOK_REPORT_MODULE;

                    ReportedAttributeType ra = new ReportedAttributeType();
                    ra.ConceptID = BookProvider.MSD_BOOK_REPORT_TYPE;
                    ra.Value.UpdateDefaultText(((TableOfContents)moduleTypeNode.Tag).ToString());
                    raModule.ReportedAttributeList.Add(ra);

                    ra = new ReportedAttributeType();
                    ra.ConceptID = BookProvider.MSD_BOOK_REPORT_IDENT;
                    // TODO: uses urn instead of fullid
                    ra.Value.UpdateDefaultText(moduleNode.Id);
                    raModule.ReportedAttributeList.Add(ra);

                    atv.ReportedAttributeList.Add(raModule);
                }
            }

            // The config file
            ReportedAttributeType raConfif = new ReportedAttributeType();
            raConfif.ConceptID = BookProvider.MSD_BOOK_REPORT_CFG;

            // serialize Config
            System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(cfg.GetType());
            System.Text.StringBuilder sb = new System.Text.StringBuilder(128);
            System.IO.StringWriter sw = new System.IO.StringWriter(sb);
            x.Serialize(sw, cfg);

            raConfif.Value.UpdateDefaultText(sb.ToString());
            atv.ReportedAttributeList.Add(raConfif);

            metadataSet.AttributeValueSetList.Add(atv);

            sm.PersistInRegistry(metadataSet);
            
        }

        public MetadataSetType CreateMetaset(ArtefactRefTyped art)
        {
            MetadataSetType ms = new MetadataSetType();
            ms.AgencyId = art.AgencyId;
            ms.Id = art.Id;
            ms.Version = art.Version;
            ms.MetadataStructureRef.AgencyId = BookProvider.MSD_BOOK_GEN_AGENCY;
            ms.MetadataStructureRef.Id = BookProvider.MSD_BOOK_GEN_ID;
            ms.Name.UpdateDefaultText("Codebook generation");
            ms.AttributeValueSetList.Clear();
            ms.ReportRef = BookProvider.BOOK_REPORT_ID;
            
            return ms;
        }

        private void SetRepAttValue(AttributeValueSetType at, string conceptId, MultiLang ml)
        {
            ReportedAttributeType ra = at.ReportedAttributeList.GetReportedAttributeOfConcept(conceptId);
            if (ra != null)
                ra.Value = ml == null ? new MultiLang() : ml;
        }


        #endregion
    }
}
